package com.by.toolkitspring.support;

import cn.hutool.core.io.resource.ClassPathResource;
import com.google.common.base.Splitter;
import com.by.toolkit.utils.ExceptionUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.lionsoul.ip2region.xdb.Searcher;

import java.io.IOException;
import java.util.List;

/**
 * ip解析
 * https://gitee.com/lionsoul/ip2region/tree/master/data
 *
 * @author YanBingHao
 * @since 2024/1/17
 */
@Slf4j
public class IPAnalyzeSupport {

    private static final Splitter SPLITTER = Splitter.on("|");

    private static Searcher SEARCHER;
    private static final String ZG = "中国";
    private static final String UNKOWN = "未知";

    public static final AnalyzeInfo PLACEHOLDER_ANALYZE_INFO = AnalyzeInfo.builder()
            .country("-1")
            .province("-1")
            .city("-1")
            .agent("-1")
            .build();

    static {
        try {
            ClassPathResource classPathResource = new ClassPathResource("ip2region.xdb");
            SEARCHER = Searcher.newWithBuffer(classPathResource.readBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private IPAnalyzeSupport() {
    }

    private static class IPAnalyzeUtilHolder {
        public static final IPAnalyzeSupport INSTANCE = new IPAnalyzeSupport();
    }

    public static IPAnalyzeSupport getInstance() {
        return IPAnalyzeUtilHolder.INSTANCE;
    }

    public AnalyzeInfo analyzeXDB(String ip) {
        try {
            String search = SEARCHER.search(ip);
            if (StringUtils.isBlank(search)) {
                log.warn("[IPAnalyzeSupport][analyzeXDB] ip:[{}] searchIsNull", ip);
                return PLACEHOLDER_ANALYZE_INFO;
            }

            // 国家|区域|省份|城市|ISP
            List<String> infos = SPLITTER.splitToList(search);

            return AnalyzeInfo.builder()
                    .ip(ip)
                    .country(infos.get(0))
                    .province(infos.get(2))
                    .city(infos.get(3))
                    .agent(infos.get(4))
                    .build();
        } catch (Exception e) {
            log.warn("[IPAnalyzeSupport][analyzeXDB] ip:[{}] hasException:[{}]", ip, ExceptionUtil.getStackTrace(e));
            return PLACEHOLDER_ANALYZE_INFO;
        }
    }

    public AnalyzeInfo analyze(String ip) {
        return IPAnalyzeSupport.getInstance().analyzeXDB(ip);
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class AnalyzeInfo {

        private String ip;

        private String country;

        private String province;

        private String city;

        private String agent;

    }

}
